package org.anachronos.jeep.agent.instrumentation;

import java.lang.instrument.ClassFileTransformer;
import java.lang.instrument.IllegalClassFormatException;
import java.security.ProtectionDomain;
import java.util.Set;

import org.ow2.util.asm.ClassReader;
import org.ow2.util.asm.ClassVisitor;
import org.ow2.util.asm.ClassWriter;

import com.google.common.base.Predicate;


public abstract class ClassTransfomerTemplate implements ClassFileTransformer, Predicate<Class<?>> {

	final public byte[] transform(ClassLoader loader, String className,
			Class<?> classBeingRedefined, ProtectionDomain protectionDomain,
			byte[] b) throws IllegalClassFormatException {
		final ClassReader classReader = new ClassReader(b);
		final ClassWriter classWriter = new ClassWriter(classReader, ClassWriter.COMPUTE_FRAMES|ClassWriter.COMPUTE_MAXS);
		final ClassVisitor classVisitor = createClassVisitor(className, classWriter);
		if (classVisitor != null) {
			classReader.accept(classVisitor, ClassReader.EXPAND_FRAMES);
			return classWriter.toByteArray();
		} else {
			return b;
		}
	}

	protected abstract ClassVisitor createClassVisitor(String className, ClassWriter classWriter);
	
	protected final boolean implementsAnInterface(final Class<?> clazz, final Set<String> interfaces) {
		for (Class<?> interfaze : clazz.getInterfaces()) {
			if (interfaces.contains(interfaze.getName())) {
				return true;
			}
		}
		return false;
	}
}
